package android.textIt.backend.dao;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import textapp.connector.message.BooleanResponse;
import textapp.connector.message.PollResponse;
import textapp.connector.message.RegResponse;
import textapp.connector.model.UserModel;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.textIt.backend.Properties;
import android.textIt.backend.database.DBProperties;
import android.textIt.backend.database.DatabaseHelper;
import android.textIt.backend.model.Group;
import android.textIt.backend.model.User;
import android.textIt.util.TextItUtil;

import com.google.gson.Gson;

public class UserDao {
  private final DatabaseHelper helper;
  private Context context;

  public UserDao(Context ctx) {
    helper = new DatabaseHelper(ctx);
    context = ctx;
  }

  public User getUserbyID(int id) {
    Cursor c = helper.getByID(id, DBProperties.USER_TABLE);
    if (c.getCount() > 0) {
      return new User(c);
    }
    else
      return null;
  }

  public User findUserByNumber(long phone) {
    Cursor c = helper.findUserByNumber(phone);
    if (c.getCount() > 0) {
      return new User(c);
    }
    else
      return null;
  }

  public void createUser(User user) {

    if (findUserByNumber(user.getPhone()) == null) {
      long uId = helper.createUser(user);
      user.setId(uId);
      long id = helper.createGroup(new Group(user.getName(), 1));
      user.setiGroup(id);
      helper.updateUser(user);
      helper.addUsertoGroup(id, uId);
      }
    // TODO: Throw something for duplicate user or ask to update?
  }

  public void deleteUser(User user) {
    helper.deleteByID(user.getId(), DBProperties.USER_TABLE);
  }

  public void updateUser(User user) {
    helper.updateUser(user);
  }

  /**
   * Returns a cursor with all the users
   * 
   * @return
   */
  public List<User> getAllUsers() {
    Cursor c = helper.getAllEntries(DBProperties.USER_TABLE);
    ArrayList<User> returnList = new ArrayList<User>();
    if (c.getCount() > 0) {
      do {
        returnList.add(new User(c));
      }
      while (c.moveToNext());
    }
    return returnList;

  }

  public void registerUser(User self) {
    if(!Properties.useServer)
      return;
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(Properties.SERVER_URL + "/registerJson");

    try {
      // Add your data
      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
      nameValuePairs.add(new BasicNameValuePair("iden", Long.toString(self.getPhone())));
      nameValuePairs.add(new BasicNameValuePair("name", self.getName()));
      httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

      // Execute HTTP Post Request
      HttpResponse response = httpclient.execute(httppost);
      String returnString = inputStreamToString(response.getEntity().getContent());

      RegResponse res = new Gson().fromJson(returnString, RegResponse.class);
      self.setReference_id(res.getBody().getId());
      helper.updateUser(self);
    }
    catch (ClientProtocolException e) {
      // TODO Auto-generated catch block
    }
    catch (IOException e) {
    	String msg = e.getMessage();
      // TODO Auto-generated catch block
    }
  }

  public void updateContacts() {
    if(!Properties.useServer)
      return;
    List<User> myContacts = getAllUsers();
    ArrayList<String> postList = new ArrayList<String>();
    for (User u : myContacts) {
      postList.add(Long.toString(u.getPhone()));
    }
    Gson gson = new Gson();
    String post = gson.toJson(postList);

    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(Properties.SERVER_URL + "/pollContactJson");

    try {
      // Add your data
      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
      nameValuePairs.add(new BasicNameValuePair("contacts", post));
      httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

      // Execute HTTP Post Request
      HttpResponse response = httpclient.execute(httppost);
      String returnString = inputStreamToString(response.getEntity().getContent());

      PollResponse res = new Gson().fromJson(returnString, PollResponse.class);
      ArrayList<UserModel> users = res.getBody();

      for (UserModel u : users) {
        if(u.getStatus()!=1)
          helper.setTextItUser(u.getId(), Long.parseLong(u.getIdentity()));
      }
    }
    catch (ClientProtocolException e) {
      // TODO Auto-generated catch block
    }
    catch (IOException e) {
      // TODO Auto-generated catch block
    }
  }
  
  public void saveRegistrationId(String regid) {
    if(!Properties.useServer)
      return;

    User self = getUserbyID(1);
    if (self != null){
	    String uid = String.valueOf(self.getReference_id());
	
	    HttpClient httpclient = new DefaultHttpClient();
	    HttpPost httppost = new HttpPost(Properties.SERVER_URL + "/saveRegistrationIdJson");
	
	    try {
	      // Add your data
	      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
	      nameValuePairs.add(new BasicNameValuePair("uid", uid));
	      nameValuePairs.add(new BasicNameValuePair("regis", regid));
	      httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
	
	      // Execute HTTP Post Request
	      HttpResponse response = httpclient.execute(httppost);
	      String returnString = inputStreamToString(response.getEntity().getContent());
	
	      BooleanResponse result = new Gson().fromJson(returnString, BooleanResponse.class);
	      if (Boolean.parseBoolean(result.getBody())){
	      	TextItUtil.savePreferenceByKey(context, TextItUtil.REGISTRATION_ID_SAVED_KEY, "saved");
	      } 
	
	    }
	    catch (ClientProtocolException e) {
	      // TODO Auto-generated catch block
	    }
	    catch (IOException e) {
	      // TODO Auto-generated catch block
	    }
    }
  }

  // Fast Implementation
  private String inputStreamToString(InputStream is) throws IOException {
    String line = "";
    StringBuilder total = new StringBuilder();

    // Wrap a BufferedReader around the InputStream
    BufferedReader rd = new BufferedReader(new InputStreamReader(is));

    // Read response until the end
    while ((line = rd.readLine()) != null) {
      total.append(line);
    }

    // Return full string
    return total.toString();
  }

}
